#include "Properties.h"

using namespace rapidxml;
using namespace std;

const std::string Properties::PROPS_FILE = "config/config.xml";
const std::string Properties::ROOT_NODE = "config";
const std::string Properties::HOTELS_NODE = "hotels";
const std::string Properties::CONSULTANTS_NODE = "consultants";

void Properties::loadProperties(void){

	//Opening file
	ifstream configFile;
	configFile.open(Properties::PROPS_FILE);

	if(configFile.is_open()){
		//Reading file to string
		string fileStr, line;

		while(getline(configFile, line)){
			fileStr += line;
		}

		//Parsing
		vector<char> xml_copy(fileStr.begin(), fileStr.end());
		xml_copy.push_back('\0');
		xml_document<> doc;
		doc.parse<parse_declaration_node | parse_no_data_nodes>(&xml_copy[0]);

		//Loading properties
		xml_node<>* rootNode = doc.first_node(Properties::ROOT_NODE.c_str());

		if(rootNode){
			xml_node<>* mBoxNode = rootNode->first_node(MailBox::MBOX_NODE.c_str());
			if(mBoxNode){
				loadMailBox(mBoxNode);
			}

			xml_node<>* hotelsNode = rootNode->first_node(Properties::HOTELS_NODE.c_str());

			if(hotelsNode){
				loadHotels(hotelsNode);
			}


			xml_node<>* consultantsNode = rootNode->first_node(Properties::CONSULTANTS_NODE.c_str());

			if(consultantsNode){
				loadConsultants(consultantsNode);
			}
		}

		configFile.close();
	}
}
void Properties::loadMailBox(rapidxml::xml_node<>* mBoxNode){
	std::string mailAddr(mBoxNode->first_node(MailBox::MBOX_EMAIL_NODE.c_str())->value());
	std::string replyTo(mBoxNode->first_node(MailBox::MBOX_REPLYTO_NODE.c_str())->value());
	std::string projectName(mBoxNode->first_node(MailBox::MBOX_PROJECT_NAME_NODE.c_str())->value());
	//std::string senderName(mBoxNode->first_node(MailBox::MBOX_SENDER_NAME_NODE.c_str())->value());
	//std::string login(mBoxNode->first_node(MailBox::MBOX_LOGIN_NODE.c_str())->value());
	//std::string password(mBoxNode->first_node(MailBox::MBOX_PASSWORD_NODE.c_str())->value());
	//std::string server(mBoxNode->first_node(MailBox::MBOX_SERVER_NODE.c_str())->value());

	//std::stringstream portBuffer;
	//portBuffer << mBoxNode->first_node(MailBox::MBOX_PORT_NODE.c_str())->value();
	//int port;
	//portBuffer >> port;

	//std::stringstream sslBuffer;
	//sslBuffer << mBoxNode->first_node(MailBox::MBOX_SSL_NODE.c_str())->value();
	//bool useSSL;
	//sslBuffer >> useSSL;

	std::stringstream defaultMailClientBuffer;
	defaultMailClientBuffer << mBoxNode->first_node(MailBox::MBOX_DEFAULT_MAIL_CLIENT_NODE.c_str())->value();
	bool useDefaultMailClient;
	defaultMailClientBuffer >> useDefaultMailClient;

	mailBox = new MailBox(mailAddr, replyTo, projectName, /*, senderName, login, password, server, port, useSSL,*/ useDefaultMailClient);
}

void Properties::loadHotels(xml_node<>* hotelsNode){
	xml_node<>* hotelNode;

	for(hotelNode = hotelsNode->first_node(Hotel::HOTEL_NODE.c_str()); hotelNode; hotelNode = hotelNode->next_sibling()){

		char* name = hotelNode->first_node(Hotel::HOTEL_NAME_NODE.c_str()) == 0 ? 0 : hotelNode->first_node(Hotel::HOTEL_NAME_NODE.c_str())->value();
		char* mail = hotelNode->first_node(Hotel::HOTEL_MAIL_NODE.c_str()) == 0 ? 0 : hotelNode->first_node(Hotel::HOTEL_MAIL_NODE.c_str())->value();

		addHotel(new Hotel( name == 0 ? "" : name,
							mail == 0 ? "" : mail));
	}
}

void Properties::loadConsultants(xml_node<>* consultantsNode){
	xml_node<>* consultantNode;

	for(consultantNode = consultantsNode->first_node(Consultant::CONS_NODE.c_str()); consultantNode; consultantNode = consultantNode->next_sibling()){

		bool isSmoker = false;

		if(consultantNode->first_node(Consultant::CONS_SMOKE_NODE.c_str())){
			std::stringstream smokerBuffer;
			smokerBuffer << consultantNode->first_node(Consultant::CONS_SMOKE_NODE.c_str())->value();
			smokerBuffer >> isSmoker;
		}

		char* firstName = consultantNode->first_node(Consultant::CONS_FIRST_NAME_NODE.c_str()) == 0 ? 0 : consultantNode->first_node(Consultant::CONS_FIRST_NAME_NODE.c_str())->value();
		char* name = consultantNode->first_node(Consultant::CONS_NAME_NODE.c_str()) == 0 ? 0 : consultantNode->first_node(Consultant::CONS_NAME_NODE.c_str())->value();
		char* mail = consultantNode->first_node(Consultant::CONS_MAIL_NODE.c_str()) == 0 ? 0 : consultantNode->first_node(Consultant::CONS_MAIL_NODE.c_str())->value();
		char* accor = consultantNode->first_node(Consultant::CONS_ACCOR_NODE.c_str()) == 0 ? 0 : consultantNode->first_node(Consultant::CONS_ACCOR_NODE.c_str())->value();

		addConsultant(new Consultant(	firstName == 0?"":firstName,
										name == 0?"":name,
										mail == 0?"":mail,
										accor == 0?"":accor,
										isSmoker));
	}
}

void Properties::saveProperties(void){

	ofstream configFile;
	configFile.open(Properties::PROPS_FILE);

	if(configFile.is_open()){
		xml_document<> doc;
		xml_node<>* rootNode = doc.allocate_node(node_element, Properties::ROOT_NODE.c_str());

		//Mail box
		rootNode->append_node(mailBox->constructNode(&doc));

		//Hotels
		xml_node<>* hotelNode = doc.allocate_node(node_element, Properties::HOTELS_NODE.c_str());

		list<Hotel*>::iterator hotelIterator;
		for(hotelIterator = getHotels()->begin(); hotelIterator != getHotels()->end(); hotelIterator++){
			hotelNode->append_node((*hotelIterator)->constructNode(&doc));
		}

		rootNode->append_node(hotelNode);


		//Consultants
		xml_node<>* consNode = doc.allocate_node(node_element, Properties::CONSULTANTS_NODE.c_str());

		list<Consultant*>::iterator consIterator;
		for(consIterator = getConsultants()->begin(); consIterator != getConsultants()->end(); consIterator++){
			consNode->append_node((*consIterator)->constructNode(&doc));
		}

		rootNode->append_node(consNode);

		//Writing
		doc.append_node(rootNode);
		configFile << doc;
		configFile.close();
	}
}